package com.quectel.leshan.client;

import com.eclipsesource.json.Json;
import com.eclipsesource.json.JsonObject;
import org.eclipse.californium.core.CoapClient;
import org.eclipse.californium.core.CoapResponse;
import org.eclipse.californium.core.coap.MediaTypeRegistry;
import org.eclipse.leshan.client.californium.LeshanClient;
import org.eclipse.leshan.client.californium.LeshanClientBuilder;
import org.eclipse.leshan.client.object.Security;
import org.eclipse.leshan.client.object.Server;
import org.eclipse.leshan.client.resource.ObjectsInitializer;
import org.eclipse.leshan.client.servers.ServerIdentity;
import org.eclipse.leshan.core.LwM2mId;
import org.eclipse.leshan.core.request.BindingMode;

import java.util.Map;
import java.util.Scanner;

public class ClientOtaTest {

    public static void main(String[] args) {
        String endpoint = "123;1;2;a34bfbc40513f41676ba933c3189497b;SOTA";
        LeshanClientBuilder builder = new LeshanClientBuilder(endpoint);

        // create objects
        ObjectsInitializer initializer = new ObjectsInitializer();
        initializer.setInstancesForObject(LwM2mId.SECURITY, Security.noSec("coap://127.0.0.1:5683", 1000));
        initializer.setInstancesForObject(LwM2mId.SERVER, new Server(1000, 5 * 60, BindingMode.U, false));

        //添加设备（需继承自BaseInstanceEnabler）
        TestClientDevice testClientDevice = new TestClientDevice();
        initializer.setInstancesForObject(LwM2mId.DEVICE, testClientDevice);
        //initializer.setInstancesForObject(LwM2mId.DEVICE, new Device("Eclipse Leshan", "model12345", "12345", "U"));

        // add it to the client
        builder.setObjects(initializer.createAll());

        LeshanClient client = builder.build();
        client.start();

        //创建服务停止时的钩子，销毁客户端（同时会通知服务端设备下线）
        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
            client.destroy(true); // send de-registration request before destroy
        }));

        //输入命令触发相应的动作
        inputCmd();

    }

    private static void sendCoapRequest(Map<String, ServerIdentity> registeredServers) {
        registeredServers.forEach((k, serverIdentity) -> {
            //注意CoapClient的uri地址，ip:port后面带的 ’request_test’ 是服务端CoapResource的名称，比如这里就会找name是的request_test的CoapResource
            CoapClient coapClient = new CoapClient(serverIdentity.getUri() + "/request_test");
            try {
                //发起post请求，payload是请求的内容，CoapResponse是服务端返回的内容
                CoapResponse coapResponse = coapClient.post("abc123", MediaTypeRegistry.TEXT_PLAIN);
                System.out.println(coapResponse.getResponseText());
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
    }

    private static void requestCoapUrl(String url) {
        //url = "coap://127.0.0.1:5683/firmwarePackage/11/s3/1598256565207_version.zip"
        CoapClient coapClient = new CoapClient(url);
        try {
            CoapResponse coapResponse = coapClient.get();
            System.out.println("Response result : " + coapResponse.getCode() + " -- " + coapResponse.getResponseText());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static void requestCoapUrl(String url,String payload) {
        //url = "coap://127.0.0.1:5683/firmwarePackage/11/s3/1598256565207_version.zip"
        CoapClient coapClient = new CoapClient(url);
        try {
            CoapResponse coapResponse = coapClient.post(payload, MediaTypeRegistry.APPLICATION_JSON);
            System.out.println("Response result : " + coapResponse.getCode() + " -- " + coapResponse.getResponseText());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static void inputCmd() {
        try (Scanner scanner = new Scanner(System.in)) {
            while (scanner.hasNext()) {
                String command = scanner.next();
                switch (command) {
                    case "p":
                        System.out.println("plan check ...");
                        JsonObject jsonObject = new JsonObject();
                        jsonObject.add("imei", "abc123");
                        jsonObject.add("uid", "11");
                        jsonObject.add("pk", "63ef9d66ae6c1dd12c0a62a42be4e21f");
                        requestCoapUrl("coap://127.0.0.1:5683/sotaUpgrade/planCheck",jsonObject.toString());
                        break;
                    case "c":
                        System.out.println("component check ...");
                        JsonObject json = new JsonObject();
                        json.add("planId", 90);
                        json.add("imei", "abc123");
                        json.add("ci", "A1");
                        json.add("version", "M_01");
                        json.add("battery", 90);
                        json.add("rsrp", -10);
                        requestCoapUrl("coap://127.0.0.1:5683/sotaUpgrade/taskCheck", json.toString());
                        break;
                    case "r":
                        System.out.println("please input status code ...");
                        int code = scanner.nextInt();
                        System.out.println("report status ... ");
                        JsonObject reportJson = new JsonObject();
                        reportJson.add("planId", 90);
                        reportJson.add("imei", "abc123");
                        reportJson.add("ci", "A1");
                        reportJson.add("version", "M_02");
                        reportJson.add("code", code);
                        reportJson.add("msg", getStatusCodeMsg(code));
                        requestCoapUrl("coap://127.0.0.1:5683/sotaUpgrade/statusReport",reportJson.toString());
                        break;
                    case "hello":
                        System.out.println("hello ...");
                        requestCoapUrl("coap://127.0.0.1:5683/hello/123");
                        break;
                    case "download":
                        System.out.println("hello ...");
                        requestCoapUrl("coap://127.0.0.1:5683/firmwarePackage/11/s3/1598256565207_version.zip");
                        break;
                    default:
                        System.out.println("Unknown command !");
                }
            }
        }
    }

    private static String getStatusCodeMsg(int code) {
        String msg;
        switch (code) {
            case 3:
                msg = "downloading";
                break;
            case 4:
                msg = "downloaded";
                break;
            case 6:
                msg = "upgrade start";
                break;
            case 7:
                msg = "upgrade success";
                break;
            default:
                msg = "unknown code";
        }
        return msg;
    }

}
